package com.yazi.mxz.common.service.impl;

import java.util.List;

import javax.annotation.Resource;

import com.myframework.smhj.common.exception.MyEntityNotExistsException;
import com.myframework.smhj.common.exception.MyException;
import com.myframework.smhj.common.exception.MyIllegalArgumentException;
import com.myframework.smhj.common.exception.MyNoPermissionException;
import com.myframework.smhj.common.tool.DateUtil;
import com.myframework.smhj.hibernate.dao.BasicService;
import com.myframework.smhj.hibernate.dao.Dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.yazi.mxz.common.ComSetting;
import com.yazi.mxz.common.client.ActFactory;
import com.yazi.mxz.common.db.dao.StoreDao;
import com.yazi.mxz.common.db.dao.StoreGiftDao;
import com.yazi.mxz.common.db.dao.StoreGoodsDao;
import com.yazi.mxz.common.db.dao.StorePromoteDao;
import com.yazi.mxz.common.entity.ValueFactory;
import com.yazi.mxz.common.entity.beans.Store;
import com.yazi.mxz.common.entity.beans.StoreGift;
import com.yazi.mxz.common.entity.beans.StoreGoods;
import com.yazi.mxz.common.entity.beans.StorePromote;
import com.yazi.mxz.common.entity.enums.SettingId;
import com.yazi.mxz.common.entity.enums.StorePromoteStatus;
import com.yazi.mxz.common.entity.enums.StorePromoteType;
import com.yazi.mxz.common.service.StorePromoteService;

@Service("storePromoteService")
public class StorePromoteServiceImpl extends BasicService<StorePromote> implements StorePromoteService {
	private static Logger log = LoggerFactory.getLogger(StorePromoteServiceImpl.class);

	@Resource
	StorePromoteDao storePromoteDao;
	@Resource
	StoreDao storeDao;
	@Resource
	StoreGoodsDao storeGoodsDao;
	@Resource
	StoreGiftDao storeGiftDao;
	
	@Override
	protected Dao<StorePromote> getDao() {
		return storePromoteDao;
	}
	
	@Override
	public StorePromote addByStore(Store store, StorePromote storePromote, 
			List<StoreGift> storeGifts) throws MyException {
		log.debug("addByStore：storeId={},name={}", store.getStoreId(), storePromote.getName());
		
		// 数量检查
		if (store.getPromRemain() <= 0) {
			throw new MyNoPermissionException("数量受限");
		}
		store.setPromRemain(store.getPromRemain() - 1);
		storeDao.merge(store);
		
		ValueFactory.validate(storePromote);
		storePromote.setStore(store);
		storePromote.setAddTime(DateUtil.getTimeStamp());
		storePromote.setUpdateTime(DateUtil.getTimeStamp());
		storePromote.setStatus(StorePromoteStatus.NOSTART.ordinal());
		storePromote.setPromoteId(null);
		storePromote = storePromoteDao.persist(storePromote);
		
		// 关联赠送商品
		if (null != storeGifts && storePromote.getType().intValue() == StorePromoteType.GIFT.ordinal()) {
			setGiftsByStore(store, storePromote, storeGifts);
		}
		
		// 触发状态更新任务
		ActFactory.actStorePromoteJob(storePromote);
		
		return storePromote;
	}

	@Override
	public StorePromote editByStore(Store store, StorePromote storePromote, 
			List<StoreGift> storeGifts) throws MyException {
		log.debug("editByStore：storeId={},promoteId={}", store.getStoreId(), storePromote.getPromoteId());
		
		StorePromote oldPromote = storePromoteDao.get(storePromote.getPromoteId());
		if (null == oldPromote) {
			throw new MyEntityNotExistsException();
		}
		if (!oldPromote.getStore().equals(store)) {
			throw new MyNoPermissionException();
		}
		
		// 防止篡改以下信息
		storePromote.setAddTime(null);
		storePromote.setStore(null);
		storePromote.setType(null);
		
		ValueFactory.combine(storePromote, oldPromote);
		oldPromote.setStatus(StorePromoteStatus.NOSTART.ordinal());
		oldPromote.setUpdateTime(DateUtil.getTimeStamp());
		storePromoteDao.merge(oldPromote);
		
		// 赠送品处理
		if (null != storeGifts && oldPromote.getType().intValue() == StorePromoteType.GIFT.ordinal()) {
			// 要先删除原有赠送品
			storeGiftDao.deleteByPromoteId(oldPromote.getPromoteId());
			// 绑定赠品
			setGiftsByStore(store, storePromote, storeGifts);
		}
		
		// 触发状态更新任务
		ActFactory.actStorePromoteJob(oldPromote);
		
		return oldPromote;
	}

	@Override
	public int endByTime() {
		int count = storePromoteDao.endByTime();
		log.debug("endByTime: count={}", count);
		return count;
	}

	@Override
	public int startByTime() {
		int count = storePromoteDao.startByTime();
		log.debug("startByTime: count={}", count);
		return count;
	}

	@Override
	public StorePromote oneNextStart() {
		StorePromote storePromote = storePromoteDao.oneNextStart();
		log.debug("oneNextStart：{}", 
				null == storePromote ? "None" : DateUtil.getDateTimeStr(storePromote.getStartTime()));
		return storePromote;
	}

	@Override
	public StorePromote oneNextEnd() {
		StorePromote storePromote = storePromoteDao.oneNextEnd();
		log.debug("oneNextEnd：{}", 
				null == storePromote ? "None" : DateUtil.getDateTimeStr(storePromote.getEndTime()));
		return storePromote;
	}

	@Override
	public void removeByStore(Store store, long promoteId) {
		log.debug("removeByStore：storeId={},promoteId={}", store.getStoreId(), promoteId);
		
		StorePromote oldPromote = storePromoteDao.get(promoteId);
		
		if (null == oldPromote || !oldPromote.getStore().equals(store)) {
			return;
		}
		
		// 删除赠送品
		if (oldPromote.getType() == StorePromoteType.GIFT.ordinal()) {
			storeGiftDao.deleteByPromoteId(promoteId);
		}
		
		// 删除目标
		storePromoteDao.delete(oldPromote);
		
		// 剩余数量
		store.setPromRemain(store.getPromRemain() + 1);
		storeDao.merge(store);
	}

	@Override
	public void editStatusByStore(Store store, long promoteId, 
			StorePromoteStatus status) throws MyException {
		log.debug("editStatusByStore: storeId={},promoteId={},status={}", 
				new Object[]{store.getStoreId(), promoteId, status});
		
		// 只能取消和重置（未开始）
		if (status != StorePromoteStatus.CANCELLED && status != StorePromoteStatus.NOSTART) {
			throw new MyNoPermissionException();
		}
		
		StorePromote storePromote = storePromoteDao.get(promoteId);
		if (null == storePromote) {
			throw new MyEntityNotExistsException();
		}
		if (!storePromote.getStore().equals(store)) {
			throw new MyNoPermissionException();
		}
		
		storePromote.setStatus(status.ordinal());
		storePromote.setUpdateTime(DateUtil.getTimeStamp());
		storePromoteDao.merge(storePromote);
		
		// 触发状态更新任务
		if (status == StorePromoteStatus.NOSTART) {
			ActFactory.actStorePromoteJob(storePromote);
		}
	}

	private void setGiftsByStore(Store store, StorePromote promote, 
			List<StoreGift> gifts) throws MyException {
		
		if (gifts.size() == 0) {
			throw new MyIllegalArgumentException("未指定赠送商品");
		}
		
		// 赠送品种上限
		int count = ComSetting.getInteger(SettingId.STORE_GIFT_AMOUNT);
		if (gifts.size() > count) {
			throw new MyIllegalArgumentException("最多可赠送" + count + "种商品");
		}
		
		for (StoreGift gift : gifts) {
			
			if (null == gift.getId() || null == gift.getId().getStoreGoodsId()) {
				throw new MyException();
			}
			
			StoreGoods storeGoods = storeGoodsDao.get(gift.getId().getStoreGoodsId());
			
			if (null != storeGoods && !storeGoods.getStore().equals(store)) {
				throw new MyException();
			}
			
			gift.setStoreGoods(storeGoods);
			gift.setStorePromote(promote);
			gift.getId().setPromoteId(promote.getPromoteId());
			storeGiftDao.persist(gift);
			// TODO 赠品库存检查
		}
	}
}
